grammar Mdl;

mdlParser: create_component_stmt
;

create_component_stmt
    : CREATE_ component_type component_name (
        OPEN_PAR attribute_def (COMMA attribute_def)*? CLOSE_PAR
        | OPEN_PAR sub_component_def  (COMMA sub_component_def)*? CLOSE_PAR
        | OPEN_PAR attribute_def (COMMA attribute_def)*? (COMMA sub_component_def)*? CLOSE_PAR
        | OPEN_PAR attribute_def (COMMA attribute_def)*? (COMMA sub_component_def)*? (COMMA attribute_def)*? (COMMA sub_component_def)*? CLOSE_PAR
    )
;

attribute_def
    : attribute_name (OPEN_PAR attribute_value ? CLOSE_PAR ?)
;

sub_component_def
    : sub_component_type sub_component_name (
              OPEN_PAR attribute_def (COMMA attribute_def)*? CLOSE_PAR
          )
;


// TODO: check all names below

component_type
    : COMPONENT_TYPE
;

component_name
    : any_name
;

sub_component_type
    : SUB_COMPONENT_TYPE
;

sub_component_name
    : any_name
;

attribute_name
    : any_name
;

attribute_value
    : any_value
;


any_name
    : IDENTIFIER
    | keyword
    | OPEN_PAR any_name CLOSE_PAR
;


keyword
    : CREATE_
;

any_value
    : bool_value
    | number_value
    | string_value
    | expression_value
    | xml_value
;

string_value
    : STRING_LITERAL (COMMA STRING_LITERAL)*?
;
number_value
    : NUMERIC_LITERAL
;
bool_value
    : TRUE
    | FALSE
;
xml_value
    : XML_LITERAL
;
expression_value
    : EXPRESSION_LITERAL
;

// http://www.sqlite.org/lang_keywords.html
CREATE_            : 'RECREATE';

COMPONENT_TYPE  :
    'Accountmessage'
    | 'Adminsection'
    | 'Applicationfamilylicensemodel'
    | 'Applicationuserlicensemodel'
    | 'Appsecurityrule'
    | 'Atomicsecurity'
    | 'Checklisttype'
    | 'Componentpropertyset'
    | 'Componentsecurity'
    | 'Control'
    | 'Controlcode'
    | 'Dashboard'
    | 'Docatomicsecurity'
    | 'Docfield'
    | 'Docfielddependency'
    | 'Docfieldlayout'
    | 'Doclifecycle'
    | 'Docmatchingrule'
    | 'Docparticipantrule'
    | 'Docrelationshiptype'
    | 'Doctype'
    | 'Documentaction'
    | 'Documentpanel'
    | 'Documenttrainingaction'
    | 'Emailprocessor'
    | 'Formattedoutput'
    | 'Integrationrule'
    | 'Job'
    | 'Jobmetadata'
    | 'Layout'
    | 'Layoutnestingtype'
    | 'Layoutprofile'
    | 'Layoutrule'
    | 'Lifecyclestatetype'
    | 'Lifecyclestatetypeassociation'
    | 'Link'
    | 'Listlayout'
    | 'Matchingrule'
    | 'Messagedeliveryeventhandler'
    | 'Messagegroup'
    | 'Messageprocessor'
    | 'Mobileshareactionconfig'
    | 'Mobiletab'
    | 'Notificationtemplate'
    | 'Object'
    | 'Objectaction'
    | 'Objectclasstrigger'
    | 'Objectcontrol'
    | 'Objectcontrolcode'
    | 'Objectlifecycle'
    | 'Objectlifecyclestagegroup'
    | 'Objectsecurity'
    | 'Objecttype'
    | 'Objectvalidation'
    | 'Objectworkflow'
    | 'Overlaytemplate'
    | 'Page'
    | 'Pagecontrollercode'
    | 'Pagelayout'
    | 'Pagelink'
    | 'Permissionset'
    | 'Picklist'
    | 'Queue'
    | 'Recordaction'
    | 'Recordroleoverrides'
    | 'Recordtrigger'
    | 'Recordworkflowaction'
    | 'Renditionprofile'
    | 'Renditiontype'
    | 'Report'
    | 'Reportexceltemplate'
    | 'Reporttype'
    | 'Rolepermissionset'
    | 'Savedview'
    | 'Sdkjob'
    | 'Searchablefield'
    | 'Searchcollection'
    | 'Securityprofile'
    | 'Sharingrule'
    | 'Signaturepage'
    | 'Tab'
    | 'Tabcollection'
    | 'Tag'
    | 'Uiwidget'
    | 'Userdefinedclass'
    | 'Userdefinedmodel'
    | 'Userdefinedservice'
    | 'Vaulttoken'
    | 'Webapi'
;

SUB_COMPONENT_TYPE  :
    'Adminlink'
    | 'Applicationuserlicensetype'
    | 'Appsecurityfield'
    | 'Appsecurityassignment'
    | 'Fieldsecurity'
    | 'Objectcontrolsecurity'
    | 'Actionsecurity'
    | 'Workflowactionsecurity'
    | 'Relationshipsecurity'
    | 'Checklistmatchingfield'
    | 'Componentproperty'
    | 'Componentattributepermission'
    | 'Docworkflowactionsecurity'
    | 'Docactionsecurity'
    | 'Doclifecyclerole'
    | 'Doclifecyclestate'
    | 'Doclifecycleevent'
    | 'Docmatchingcriterion'
    | 'Docparticipantcriterion'
    | 'Queryobjectrule'
    | 'Fieldrule'
    | 'Changestatejobaction'
    | 'Sendnotificationjobaction'
    | 'Sendobjectnotificationjobaction'
    | 'Changeobjectstatejobaction'
    | 'Noopjobaction'
    | 'Objectnoopjobaction'
    | 'Httppostjobaction'
    | 'Sdkbatchjobaction'
    | 'Edlmatchjobaction'
    | 'Rmsintegrationjobaction'
    | 'Flashreportjobaction'
    | 'scheduled_edc_job_actions'
    | 'Scheduleddataexportjobaction'
    | 'Documentperiodicreviewjobaction'
    | 'Objectlayout'
    | 'Listlayoutitem'
    | 'Message'
    | 'Field'
    | 'Index'
    | 'Objectlifecyclestate'
    | 'Objectlifecyclestateentrycriterion'
    | 'Objectlifecyclestateentryaction'
    | 'Objectlifecyclestateuseraction'
    | 'Objectlifecycleevent'
    | 'Objectlifecyclerole'
    | 'Objectlifecyclepermission'
    | 'Objectlifecyclestage'
    | 'Statefieldlevelsecurity'
    | 'Typefield'
    | 'Typeaction'
    | 'Objectworkflowstep'
    | 'WorkflowCancelationAction'
    | 'Overlayoverride'
    | 'Picklistentry'
    | 'Queueconnection'
    | 'Searchcollectionsection'
    | 'Sharingrole'
    | 'Subtab'
    | 'Tabcollectionitem'
    | 'Uiwidgetattribute'
;


OPEN_PAR  : '(';
CLOSE_PAR : ')';
COMMA     : ',';
TRUE     : 'true';
FALSE     : 'false';

EXPRESSION_LITERAL: '[' (Bracket_Escaped | ( ~'[' | ~']'))*? ']';
Bracket_Escaped
    : '\\' ('[' | ']')
    ;
XML_LITERAL: '{' (Brace_Escaped | ( ~'{' | ~'}'))*? '}';
Brace_Escaped
    : '\\' ('{' | '}')
    ;

IDENTIFIER:
    '"' (~'"' | '""')* '"'
    | '`' (~'`' | '``')* '`'
    | '[' ~']'* ']'
    | [a-zA-Z_.]*
    | [a-zA-Z_.][a-zA-Z_.0-9]*
;

NUMERIC_LITERAL: ((DIGIT+ ('.' DIGIT*)?) | ('.' DIGIT+)) ('E' [-+]? DIGIT+)? | '0x' HEX_DIGIT+;

BIND_PARAMETER: '?' DIGIT* | [:@$] IDENTIFIER;

STRING_LITERAL: '\'' ( ~'\'' | '\'\'')* '\'';

BLOB_LITERAL: 'X' STRING_LITERAL;

SINGLE_LINE_COMMENT: '--' ~[\r\n]* (('\r'? '\n') | EOF) -> channel(HIDDEN);

MULTILINE_COMMENT: '/*' .*? '*/' -> channel(HIDDEN);

SPACES: [ \u000B\t\r\n] -> channel(HIDDEN);

UNEXPECTED_CHAR: .;



fragment HEX_DIGIT : [0-9A-F];
fragment DIGIT     : [0-9];

WS : [ \t\r\n]+ -> skip ;